#ifndef _SERVER_LIBRARY_OBJECT_H
#define _SERVER_LIBRARY_OBJECT_H

#include "stdio.h"
#include "string.h"
#include "ctype.h"
#include "stddef.h"

#include "server_typedef.h"
#include "server_log.h"
#include "server_user.h"
#include "server_tools.h"
#include "server_assert.h"
#include "server_global_config.h"

#define LIBRARY_OBJECT_DATA_FILE_PATH "./server/data/library_object_data.dat"

// =============================================图书信息层==============================================

typedef enum _ObjectType{
    OBJECT_TYPE_BOOK = 0,           // 以单一体裁或主题为核心，经过系统编排、装订成册的出版物
    OBJECT_TYPE_PERIODICAL,         // 定期或不定期出版的连续性出版物，以固定刊名发行，包含多篇不同作者的文章，内容聚焦特定领域
    OBJECT_TYPE_NEWSPAPER,          // 以新闻报道和时事评论为核心内容的定期出版物，强调时效性，通常每日或每周发行，篇幅较短，内容碎片化
} ObjectType;

typedef enum _BookClassification{
    BOOK_CLASSIFICATION_FICTION = 0, // Fiction
    BOOK_CLASSIFICATION_SCIENCE,     // Science
    BOOK_CLASSIFICATION_TECHNOLOGY,  // Technology
    BOOK_CLASSIFICATION_HISTORY,     // History
    BOOK_CLASSIFICATION_LITERATURE,  // literature
    BOOK_CLASSIFICATION_ART,         // Art
} BookClassification;

typedef struct _BookInfo{
    BookClassification      classification;
    wchar_t                 ISBN[20];           // ISBN number      : 12 digits + 1 check digit + '\0'
    wchar_t                 author[32];         // Author name      : 32 characters max, xxx | xxx, xxx ...
    wchar_t                 publisher[32];      // Publisher name   : 32 characters max
    wchar_t                 publish_date[16];   // Publish date     : xxxx年xx月xx日 | xxxx-xx-xx | xxxx年xx月
} BookInfo;

typedef struct _PeriodicalInfo{
    int                     volume;                // 卷号
    int                     issue;                 // 期号
    wchar_t                 ISSN[9];               // ISSN              : 8 digits + '\0'
    wchar_t                 publisher[32];         // Publisher name    : 32 characters max
    wchar_t                 publication_date[16];  // Publish date      : xxxx年xx月xx日 | xxxx-xx-xx | xxxx年xx月
} PeriodicalInfo;

typedef struct _NewspaperInfo{
    wchar_t                ISSN[9];               // ISSN              : 8 digits + '\0'
    wchar_t                publisher[32];         // Publisher name    : 32 characters max
    wchar_t                publication_date[16];  // Publish date      : xxxx年xx月xx日 | xxxx-xx-xx | xxxx年xx月
} NewspaperInfo;

typedef union _ObjectInfo{
    BookInfo        book;             // Book information
    PeriodicalInfo  periodical;       // Periodical information
    NewspaperInfo   newspaper;         // Newspaper information
} ObjectInfo;

typedef struct _LibraryObject {
    uint32          id;                 // unique id
    ObjectType      type;               // Type
    wchar_t         title[32];          // title  : 32 characters max
    ObjectInfo      info;               // Object information
    float           unit_price_yuan;    // unit price       : unit > Yuan(¥)
    uint16          remain_num;
    uint16          total_num;
} LibraryObject;

// =============================================功能函数类型定义层==============================================

typedef struct _ObjectCountAnalyzeData{
    // ======Object numbers======
    uint64      total_objects;                  // Total unique objects
    uint64      total_books;                    // Total unique books
    uint64      total_periodicals;              // Total unique periodicals
    uint64      total_newspapers;               // Total unique newspapers

    uint64      total_objects_num;              // Total number of objects
    uint64      total_books_num;                // Total number of books
    uint64      total_periodicals_num;          // Total number of periodicals
    uint64      total_newspapers_num;           // Total number of newspapers

    // ======Object lending statistics======
    uint64      total_lent_objects_num;         // Total number of lent objects
    uint64      total_lent_books_num;           // Total number of lent books
    uint64      total_lent_periodicals_num;     // Total number of lent periodicals
    uint64      total_lent_newspapers_num;      // Total number of lent newspapers
    uint64      total_remain_objects_num;       // Total number of lent objects
    uint64      total_remain_books_num;         // Total number of lent books
    uint64      total_remain_periodicals_num;   // Total number of lent periodicals
    uint64      total_remain_newspapers_num;    // Total number of lent newspapers
} ObjectCountAnalyzeData;

typedef enum _ObjectFunctionReturn {
    // 图书馆物品借操作返回值
    BOOK_LEND_SUCCESS = 0,          // 成功
    BOOK_LEND_NOT_EXIST,            // 物品不存在
    BOOK_LEND_NOT_ENOUGH_BOOK,      // 可借阅图书数量不足
    BOOK_LEND_NOT_ENOUGH_USER_COUNT,// 用户数量不足
    BOOK_LEND_PERMISSION_DENIED,    // 权限不足
    
    // 图书馆物品归还操作返回值
    BOOK_RETURN_SUCCESS,            // 归还成功
    BOOK_RETURN_NOT_EXIST,          // 物品不存在
    BOOK_RETURN_INVALID,            // 不合法的归还

    // 图书馆物品续借操作返回值
    BOOK_RENEW_SUCCESS,             // 续借成功
    BOOK_RENEW_LIMIT_EXCEEDED,      // 续借次数超过限制

    BOOK_UNKNOWN_ERROR,        // 未知错误
} ObjectFunctionReturn;

// =============================================物品信息存储链表定义层==============================================
// 全量信息结构体链表
typedef struct _LibraryObjectNode {
    LibraryObject                 object; // library object
    struct _LibraryObjectNode   * prev;   // Pointer to the previous node in the linked list
    struct _LibraryObjectNode   * next;   // Pointer to the next node in the linked list
} LibraryObjectNode;

typedef struct _LibraryObjectList{
    LibraryObjectNode * first_node;        // Pointer to the first node in the linked list
    LibraryObjectNode * last_node;         // Pointer to the last node in the linked list
    uint64              total_objects;     // Total number of objects in the list
} LibraryObjectList;

// 指结构体指针链表
typedef struct _LibraryObjectPtrNode {
    LibraryObject                  * object; // Pointer to the library object
    struct _LibraryObjectPtrNode   * prev;   // Pointer to the previous node in the linked list
    struct _LibraryObjectPtrNode   * next;   // Pointer to the next node in the linked list
} LibraryObjectPtrNode;

typedef struct _LibraryObjectPtrList{
    LibraryObjectPtrNode * first_node;       // Pointer to the first node in the linked list
    LibraryObjectPtrNode * last_node;        // Pointer to the last node in the linked list
    uint64                 total_objects;    // Total number of objects in the list
} LibraryObjectPtrList;

typedef struct _User User;

extern uint8 server_library_object_list_load_flag;      // 图书馆物品列表加载成功标志

extern LibraryObjectList server_library_object_list;    // 图书馆物品链表

// 图书馆物品查找返回
LibraryObjectNode       * server_find_object_by_id(uint32 id);
LibraryObjectPtrList    * server_find_object_by_incomplete_name(wchar_t * name, StringIsSensitive is_sensitive);

// 图书馆物品增加
uint8 server_add_object(LibraryObject * object);

// 图书馆物品删除
uint8 server_delete_object_node(LibraryObjectNode * delete_node);
uint8 server_delete_object_by_id(uint32 id);

// 图书馆物品修改
uint8 server_modify_object(LibraryObjectNode * object_node, LibraryObject * new_object_data);

// 图书馆物品借还操作
ObjectFunctionReturn    server_lend_object  (uint32 id, uint16 count, User * user_p);
ObjectFunctionReturn    server_return_object(uint32 id, uint16 count, User * user_p);

// 图书馆物品续借操作
ObjectFunctionReturn    server_renew_object(uint16 record_list_number, User * user_p);

// 图书馆物品数据加载
uint8 server_load_object_data(void);
// 图书馆物品数据保存
uint8 server_save_object_data(void);

// 图书馆物品数据分析
ObjectCountAnalyzeData server_count_analyze_object_data(void);

#endif
